﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Text;

namespace SCQS.Handler
{
    public class GenerateSecurityCode
    {
        private static char[] table = new char[] 
        { '0','1','2','3',
          '4','5','6','7',
          '8','9','A','B',
          'C','D','E','F',
          'G','H','I','J',
          'K','L','M','N',
          'O','P','Q','R',
          'S','T','U','V',
          'W','X','Y','Z' };

        private static int[] IntTable = new int[]{
            16,7,20,21,   
            29,12,28,17,   
            1,15,23,26,   
            5,18,31,10,   
            2,8,24,14,   
            32,27,3,9,   
            19,13,30,6,   
            22,11,4,25,
            0,33,34,35
        };

        /// <summary>
        /// 生成指定数量的防伪码
        /// </summary>
        /// <param name="count"></param>
        /// <param name="startDate">有效开始日期</param>
        /// <param name="expireDate">有效截止日期</param>
        /// <returns></returns>
        public DataTable GenerateCode(int count,DateTime startDate,DateTime expireDate)
        {

            DataTable table = new DataTable();
            table.TableName = "securityCode";
            DataColumn codeIDColumn = new DataColumn("codeID", typeof(string));//编号
            codeIDColumn.Unique = true;
            table.Columns.Add(codeIDColumn);

            DataColumn digitalsColumn = new DataColumn("digitals", typeof(string));//防伪码
            table.Columns.Add(digitalsColumn);

            DataColumn startDateColumn = new DataColumn("startDate", typeof(DateTime));//有效开始日期
            table.Columns.Add(startDateColumn);

            DataColumn expireDateColumn = new DataColumn("expireDate", typeof(DateTime));//有效截止日期
            table.Columns.Add(expireDateColumn);

            DataColumn queryCountColumn = new DataColumn("queryCount", typeof(int));//查询次数
            table.Columns.Add(queryCountColumn);


            for (int i = 0; i < count; i++)
            {
                DataRow newRow = table.NewRow();
                newRow["codeID"] = Guid.NewGuid();
                newRow["digitals"] = newCode(count);
                newRow["startDate"] = startDate;
                newRow["expireDate"] = expireDate;
                newRow["queryCount"] = 0;
                table.Rows.Add(newRow);
            }
            return table;
        }

        private static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }


        /// <summary>
        /// 随机生成一个36进制的16位的字符
        /// </summary>
        public string newCode(int countIndex)
        {
            StringBuilder sb = new StringBuilder();

            Random rad = new Random(GetRandomSeed());

            for (int i = 0; i < 16; i++)
            {

                sb.Append(table[IntTable[rad.Next(0, IntTable.Length)]]);
            }

            return huanwei(sb.ToString());

        }

        /// <summary>
        /// 将16个字符转换成数据库保存形式
        /// </summary>
        public static string TransformSqlCode(string code)
        {
            code = Gueiwei(code);
            char[] chars = code.ToCharArray();
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < chars.Length; i++)
            {
                for (int j = 0; j < IntTable.Length; j++)
                {
                    if (chars[i] == table[IntTable[j]])
                    {
                        sb.Append(table[j]);
                        break;
                    }
                }
            }


            return sb.ToString();
        }
        /// <summary>
        /// 将数据库防伪码转换成查询形式
        /// </summary>
        public static string SqlCodeTransformCode(string sqlCode)
        {
            char[] chars = sqlCode.ToCharArray();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < chars.Length; i++)
            {
                for (int index = 0; index < table.Length; index++)
                {
                    if (chars[i] == table[index])
                    {
                        sb.Append(table[IntTable[index]]);
                    }
                }
            }
            return huanwei(sb.ToString());
        }
        /// <summary>
        /// 打乱16个字符排序 并且返回
        /// </summary>

        private static string huanwei(string strB)
        {

            Char[] chars = strB.ToCharArray();
            char[,] fenjie = new char[4, 4];
            int r = 0;
            int c = 0;
            char[] buma = new char[4];
            foreach (char ch in chars)
            {
                fenjie[r, c] = ch;
                if (r == 0) buma[c] = ch;
                c++;
                if (c == 4)
                {
                    c = 0;
                    r++;
                }

            }
            StringBuilder sb = new StringBuilder();
            r = 0;
            for (int i = 0; i < 16; i++)
            {
                if (i < 4) { sb.Append(fenjie[r++, 0]); if (i == 3)sb.Append('-'); }
                else if (i < 8) { sb.Append(fenjie[--r, 1]); if (i == 7)sb.Append('-'); }
                else if (i < 12) { sb.Append(fenjie[r++, 2]); if (i == 11)sb.Append('-'); }
                else if (i < 16) { sb.Append(fenjie[--r, 3]); }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 复原16字符的排序
        /// </summary>
        private static string Gueiwei(String str)
        {
            str = str.Replace("-", "");
            char[] chars = str.ToCharArray();
            StringBuilder sb = new StringBuilder();
            int row1 = 0;
            int row2 = 7;
            int row3 = 8;
            int row4 = 15;

            for (int i = 0; i < 4; i++)
            {
                sb.Append(chars[row1++]);
                sb.Append(chars[row2--]);
                sb.Append(chars[row3++]);
                sb.Append(chars[row4--]);

            }

            return sb.ToString();
        }
    }
}
